import ASlib.Trazador;
import ASlib.Hilo;

class Donald1
{
    public static final String GILITO = "Gilito";
    public static final String[] nombres = {"Jorgito","Jaimito","Juanito"};
    public static final int NSOBRINOS = nombres.length;

    static Tio gilito;
    static Sobrino[] sobrinos = new Sobrino[NSOBRINOS];
    static Cuenta cuenta = new Cuenta();

    public static void main(String[] args)
    {
        Crear_hilos();
        Lanzar_hilos();
        Esperar_hilos();
        System.out.println("-------------------------");
        System.out.println(cuenta.Saldo());
    }

    private static void Crear_hilos()
    {
        gilito = new Tio(GILITO, 2, cuenta);
        for (int i=0; i<NSOBRINOS; i++)
            sobrinos[i] = new Sobrino(nombres[i], 2*i + 4,cuenta);
    }
    private static void Lanzar_hilos()
    {
        gilito.start();
        for (int i=0; i<NSOBRINOS; i++)
            sobrinos[i].start();
    }
    private static void Esperar_hilos()
    {
        gilito.Join();
        System.out.println(gilito.nombre + " ha terminado");

        for (int i=0; i<NSOBRINOS; i++)
        {
            sobrinos[i].Join();
            System.out.println(sobrinos[i].nombre +" ha terminado");
        }
    }
}

class Tio extends Hilo
{
    private Trazador trazador;
    private Cuenta cuenta;
    public  String nombre;

    public Tio(String nombre,int columna, Cuenta cuenta)
    {
        this.nombre = nombre;
        trazador = new Trazador(columna, nombre);
        this.cuenta = cuenta;
    }
    public void run ()
    {

        trazador.Print("Soy el tio");
        trazador.Print("Mi id es "+getId());
        while (true)
        {
            this.Pausa(1000);
            trazador.Print("Ingreso 1");
            synchronized(cuenta)
            {
                cuenta.Ingresar(1);
                cuenta.notifyAll();
            }
        }
    }
}

class Sobrino extends Hilo
{
    public String nombre;
    private static int suTurno = 0, turno = 0;

    Cuenta cuenta;
    Trazador trazador;
    private int miTurno;

    public Sobrino(String nombre, int col, Cuenta cuenta)
    {
        this.nombre = nombre;
        trazador = new Trazador(col,nombre);
        this.cuenta = cuenta;
    }
    public void run ()
    {
        this.Pausa(1000);
        trazador.Print("Soy un sobrino");
        trazador.Print("Mi id es "+getId());
        while (true)
        {
            miTurno = suTurno++;
            synchronized(this.cuenta)
            {
                while (cuenta.Saldo() < 1 || miTurno != turno) this.Wait(cuenta);
                cuenta.Retirar(1);
            }
            turno += 1;
            trazador.Print("Retiro 1");
        }
    }
}

class Cuenta
{
    private float	saldo = 0;
    public  float Ingresar (float v)
    {
        float acc = saldo;
        saldo = acc + v;
        return (saldo);
    }
    public float Retirar (float v)
    {
        float acc = saldo;
        saldo = acc-v;
        if (saldo > 0) this.notifyAll();
        return (saldo);
    }
    public float Saldo()    {return (saldo);}
}
